package com.zzq.controller;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zzq.Model.Article;
import com.zzq.Model.Comment;
import com.zzq.Model.CommentRet;
import com.zzq.mapper.ArticleMapper;
import com.zzq.mapper.CommentMapper;
import com.zzq.mapper.UserMapper;
import com.zzq.utils.IResult;
import com.zzq.utils.JWTUtil;
import com.zzq.utils.Log;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api("评论接口")
@Controller
@RequestMapping("/comment")
public class CommentController {
    @Autowired
    CommentMapper commentMapper;
    @Autowired
    ArticleMapper articleMapper;
    @Autowired
    UserMapper userMapper;

    @ApiOperation(value = "发表评论", response = Comment.class)
    @ApiImplicitParams({
            @ApiImplicitParam(paramType="query", name = "articleId", value = "文章序号", dataType = "Integer"),
            @ApiImplicitParam(paramType="query", name = "body", value = "评论内容", dataType = "String")
    })
    @PostMapping("post.do")
    @ResponseBody
    public IResult post(@RequestHeader("token") String token, HttpServletRequest request) {
        try {
            int articleId = Integer.parseInt(request.getParameter("articleId"));
            String body = request.getParameter("body");

            Claims claims = JWTUtil.verifyToken(token);
            int userId = Integer.parseInt((String) claims.get("jti"));

            Article article = null;
            article = articleMapper.getById(articleId);
            if(article == null) {
                return IResult.error("文章不存在");
            }

            if(body == null &&  "".equals(body)) {
                return IResult.error("发表评论请填写评论内容！");
            } else if(body.length() > 3000) {
                return IResult.error("评论内容不能超过3000字");
            }
            Comment comment = new Comment();
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            comment.setArticleId(articleId).setUserId(userId).setBody(body).setCreateTime(now.format(df));

            commentMapper.post(comment);
            return IResult.success("发表成功", comment);
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("删除指定id评论")
    @ApiImplicitParam(paramType="path", name = "commentId", value = "评论编号", dataType = "Integer")
    @DeleteMapping("{commentId}")
    @ResponseBody
    public IResult deleteById(@RequestHeader("token") String token, @PathVariable("commentId") Integer commentId) {
        try {
            Claims claims = JWTUtil.verifyToken(token);
            int userId = Integer.parseInt((String) claims.get("jti"));

            Comment comment = commentMapper.getById(commentId);

            if(comment == null) {
                return IResult.error("评论不存在");
            }

            if(comment.getUserId() == userId || userMapper.getById(userId).getIsSuperuser() == 1) {
                commentMapper.deleteById(commentId);
                return IResult.success("删除成功");
            }
            return IResult.error("只有管理员和自己可以删除评论");
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("删除选定评论")
    @ApiImplicitParam(paramType="body", name = "commentIds", value = "评论编号列表(格式如: [2,3])", dataType = "Integer")
    @DeleteMapping("admin/deleteByIds.do")
    @ResponseBody
    public IResult deleteByIds(@RequestBody List<Integer> commentIds) {
        try {
            commentMapper.deleteByIds(commentIds);
            return IResult.success("删除成功");
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiModelProperty("评论点赞")
    @ApiImplicitParam(paramType="query", name = "commentId", value = "评论序号", dataType = "Integer")
    @PostMapping("addLikes.do")
    @ResponseBody
    public IResult addLikes(HttpServletRequest request) {
        try {
            int commentId = Integer.parseInt(request.getParameter("commentId"));

            if(commentMapper.getById(commentId) == null) {
                return IResult.error("评论不存在");
            }
            commentMapper.addLikes(commentId);
            return IResult.success();
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("取消点赞")
    @ApiImplicitParam(paramType="query", name = "commentId", value = "评论序号", dataType = "Integer")
    @PostMapping("subLikes.do")
    @ResponseBody
    public IResult subLikes(HttpServletRequest request) {
        try {
            int commentId = Integer.parseInt(request.getParameter("commentId"));

            if(commentMapper.getById(commentId) == null) {
                return IResult.error("评论不存在");
            }
            commentMapper.subLikes(commentId);
            return IResult.success();
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("更新评论")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType="path", name = "commentId", value = "评论编号", dataType = "Integer"),
            @ApiImplicitParam(paramType="query", name = "body", value = "正文", dataType = "String"),
    })
    @PostMapping("{commentId}")
    @ResponseBody
    public IResult edit(@RequestHeader("token") String token, @PathVariable("commentId") int commentId, HttpServletRequest request) {
        try {
            String body = request.getParameter("body");

            Claims claims = JWTUtil.verifyToken(token);
            int userId = Integer.parseInt((String) claims.get("jti"));

            Comment comment = commentMapper.getById(commentId);

            if(comment == null) {
                return IResult.error("文章不存在");
            }
            if(commentMapper.getById(commentId) == null) {
                return IResult.error("评论不存在");
            }
            if(comment.getUserId() == userId || userMapper.getById(userId).getIsSuperuser() == 1) {
                if(body == null ||  "".equals(body)) {
                    return IResult.error("发表评论请填写正文！");
                }
                LocalDateTime localDateTime = LocalDateTime.now();
                commentMapper.editById(commentId, body);
                return IResult.success("修改成功");
            }
            return IResult.error("只有管理员和自己可以编辑文章");
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("获取所有评论(先按点赞数逆序排序，再按创建时间逆序排序)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType="query", name = "pageNo", value = "页码", dataType = "Integer"),
            @ApiImplicitParam(paramType="query", name = "pageNum", value = "一页显示的数量", dataType = "Integer")
    })
    @GetMapping("")
    @ResponseBody
    public IResult<Comment> getAll(@RequestParam(value = "pageNo", defaultValue = "1") int pageNo, @RequestParam(value = "pageNum", defaultValue = "5") int pageNum) {
        try {
            Page<Object> objects = PageHelper.startPage(pageNo, pageNum);
            List<Comment> comments = commentMapper.getAll();
            PageInfo<Comment> pageInfo = new PageInfo<Comment>(comments);
            return IResult.success(pageInfo);
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("通过评论序号获取评论")
    @ApiImplicitParam(paramType="path", name = "articleId", value = "评论序号", dataType = "Integer")
    @GetMapping("{commentId}")
    @ResponseBody
    public IResult<Comment> getById(@PathVariable("commentId") int commentId) {
        try {
            Comment c = commentMapper.getById(commentId);
            Map<String, Object> comment = new HashMap<>();
            comment.put("id", c.getId());
            comment.put("body", c.getBody());
            comment.put("createTime", c.getCreateTime());
            comment.put("likes", c.getLikes());
            return IResult.success(comment);
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("通过评论内容获取评论")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType="query", name = "searchInfo", value = "评论内容", dataType = "String"),
            @ApiImplicitParam(paramType="query", name = "pageNo", value = "页码", dataType = "Integer"),
            @ApiImplicitParam(paramType="query", name = "pageNum", value = "一页显示的数量", dataType = "Integer")
    })
    @GetMapping("serarch.do")
    @ResponseBody
    public IResult<Comment> getByBody(String searchInfo, @RequestParam(value = "pageNo", defaultValue = "1") int pageNo, @RequestParam(value = "pageNum", defaultValue = "5") int pageNum) {
        try {
            PageHelper.startPage(pageNo, pageNum);
            List<Comment> comments = commentMapper.getByBody("%" + searchInfo + "%");
            PageInfo<Comment> pageInfo = new PageInfo<Comment>(comments);
            return IResult.success(pageInfo);
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("获取当前文章的评论(通过点赞排序评论)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType="query", name = "pageNo", value = "页码", dataType = "Integer"),
            @ApiImplicitParam(paramType="query", name = "pageNum", value = "一页显示的数量", dataType = "Integer"),
            @ApiImplicitParam(paramType="query", name = "articleId", value = "文章编号", dataType = "Integer")
    })
    @GetMapping("getByArticleIdOrderByLikes.do")
    @ResponseBody
    public IResult<Comment> getByArticleIdOrderByLikes(@RequestParam(value = "pageNo", defaultValue = "1") int pageNo, @RequestParam(value = "pageNum", defaultValue = "5") int pageNum, int articleId) {
        try {
            Page<Object> objects = PageHelper.startPage(pageNo, pageNum);
            List<Comment> comments = commentMapper.getByArticleIdOrderByLikes(articleId);
            PageInfo<Comment> pageInfo = new PageInfo<Comment>(comments);
            return IResult.success(pageInfo);
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("获取当前文章的评论(通过时间逆序排序)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType="query", name = "pageNo", value = "页码", dataType = "Integer"),
            @ApiImplicitParam(paramType="query", name = "pageNum", value = "一页显示的数量", dataType = "Integer"),
            @ApiImplicitParam(paramType="query", name = "articleId", value = "文章编号", dataType = "Integer")
    })
    @GetMapping("getByArticleId.do")
    @ResponseBody
    public IResult<Comment> getByArticleId(@RequestParam(value = "pageNo", defaultValue = "1") int pageNo, @RequestParam(value = "pageNum", defaultValue = "5") int pageNum, int articleId) {
        try {
            Page<Object> objects = PageHelper.startPage(pageNo, pageNum);
            List<CommentRet> comments = commentMapper.getByArticleId(articleId);
            PageInfo<CommentRet> pageInfo = new PageInfo<CommentRet>(comments);
            return IResult.success(pageInfo);
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("通过登录用户获取用户的评论")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType="query", name = "pageNo", value = "页码", dataType = "Integer"),
            @ApiImplicitParam(paramType="query", name = "pageNum", value = "一页显示的数量", dataType = "Integer")
    })
    @GetMapping("getByUserId.do")
    @ResponseBody
    public IResult<Comment> getByUserId(@RequestParam(value = "pageNo", defaultValue = "1") int pageNo, @RequestParam(value = "pageNum", defaultValue = "5") int pageNum, @RequestHeader("token") String token) {
        try {
            Claims claims = JWTUtil.verifyToken(token);
            int userId = Integer.parseInt((String) claims.get("jti"));

            Page<Object> objects = PageHelper.startPage(pageNo, pageNum);
            List<Comment> comments = commentMapper.getByUserId(userId);
            PageInfo<Comment> pageInfo = new PageInfo<Comment>(comments);
            return IResult.success(pageInfo);
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }

    @ApiOperation("通过当前文章编号获取评论数")
    @ApiImplicitParam(paramType="query", name = "articleId", value = "文章编号", dataType = "Integer")
    @GetMapping("getCountByArticleId.do")
    @ResponseBody
    public IResult getCountByArticleId(int articleId) {
        try {
            int count = commentMapper.getCountByArticleId(articleId);
            return IResult.success(count);
        } catch (Exception e) {
            Log.LogWarn(e.toString());
            return IResult.error(e.toString());
        }
    }
}
